home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************\
- *
- * Apple Macintosh Developer Technical Support
- *
- * Menu-handling routines
- *
- * Program: ColorReset
- * File: MenuHandler.c
- *
- * by: Forrest Tanaka
- *
- * Copyright © 1988-1992 Apple Computer, Inc.
- * All rights reserved.
- *
- \******************************************************************************/
-
-
- /******************************************************************************\
- * Header Files
- \******************************************************************************/
-
- #ifndef THINK_C
- #include <Desk.h>
- #include <Errors.h>
- #include <Memory.h>
- #include <Menus.h>
- #include <Resources.h>
- #endif
-
- #include "ColorReset.h"
- #include "MenuHandler.h"
- #include "PictDocument.h"
-
-
- /******************************************************************************\
- * Constants
- \******************************************************************************/
-
- #define rMenuBar 128 /* Resource ID of this application’s MBAR resource */
-
- #define kNumMenuGuides (mLastMenu - mApple + 1) /* Number of menu guide recs */
-
-
- /******************************************************************************\
- * Types
- \******************************************************************************/
-
- typedef struct
- {
- MenuHandle theMenu; /* Handle to this guide’s menu */
- long enables; /* Current enable flags */
- } MenuGuide;
-
-
- /******************************************************************************\
- * Prototypes
- \******************************************************************************/
-
- void DoAppleMenu(
- short menuItem);
-
- void DoFileMenu(
- short menuItem);
-
- void DoEditMenu(
- short menuItem);
-
- void DoDisplayMenu(
- short menuItem);
-
- void ResetMenuItems(void);
-
- void FixDAMenus(void);
-
-
- /******************************************************************************\
- * Variables
- \******************************************************************************/
-
- MenuGuide gMenuGuides[kNumMenuGuides]; /* Application’s menu guide records */
-
-
- /******************************************************************************\
- * Public: StartMenus
- *
- * The menu guide array is initialized with the menu handles and enable flags of
- * all menus.
- *
- * If GetNewMBar couldn’t load the MBAR resource, then it returns nil and the
- * error code is in ResError, and I can deal with the error elegantly. But, if
- * the GetNewMBar couldn’t load the menus themselves, then it’ll probably crash.
- \******************************************************************************/
-
- OSErr StartMenus()
- {
- Handle menuBar; /* Handle to the menu bar from the MBAR resource */
- short menuIndex; /* Index into menu guide records */
- OSErr error;
-
- /* Load in the menu bar */
- menuBar = GetNewMBar( rMenuBar );
- if (menuBar != nil)
- {
- /* Set it, then dispose of it because SetMenuBar makes a copy */
- SetMenuBar( menuBar );
- DisposHandle( menuBar );
-
- /* Add the desk accessories to the Apple menu */
- AddResMenu( GetMHandle( mApple ), 'DRVR' );
-
- /* Initialize the menu guide array */
- for (menuIndex = 0; menuIndex < kNumMenuGuides; menuIndex++)
- {
- gMenuGuides[menuIndex].theMenu = GetMHandle( menuIndex + mApple );
- gMenuGuides[menuIndex].enables = (**gMenuGuides[menuIndex].
- theMenu).enableFlags;
- }
-
- /* Draw the menu bar */
- DrawMenuBar();
- error = noErr;
- }
- else
- {
- error = ResError();
- if (error == noErr)
- error = resNotFound;
- if (error != resNotFound && error != memFullErr)
- error = dsSysErr;
- }
- return error;
- }
-
-
- /******************************************************************************\
- * Public: DoMenuChoice
- *
- * This routine should be self-explanatory.
- \******************************************************************************/
-
- void DoMenuChoice(
- long menuChoice) /* Return value from MenuSelect or MenuKey */
- {
- short menuNum; /* Menu number of chosen menu */
- short menuItem; /* Item number of chosen menu item */
-
- if (menuChoice != 0)
- {
- /* Get the chosen menu item and menu number */
- menuNum = hiWord( menuChoice );
- menuItem = loWord( menuChoice );
-
- /* Dispatch the appropriate menu-handling routine */
- if (menuNum == mApple)
- DoAppleMenu( menuItem );
- else if (menuNum == mFile)
- DoFileMenu( menuItem );
- else if (menuNum == mEdit)
- DoEditMenu( menuItem );
- else if (menuNum == mDisplay)
- DoDisplayMenu( menuItem );
- HiliteMenu( 0 );
- }
- }
-
-
- /******************************************************************************\
- * Private: DoAppleMenu - Handle an Apple menu item choice
- *
- * This routine is called whenever it’s determined that the chosen menu item was
- * in the Apple menu. If the chosen menu item that’s passed in the menuItem
- * parameter wasn’t the About item, the name of the menu item is retrieved and
- * then OpenDeskAcc is called with this name so that the desk accessory by that
- * name is opened. The Process Manager can launch desk accessories, but
- * OpenDeskAcc should still be used if the user chooses any item in the Apple
- * menu.
- \******************************************************************************/
-
- static void DoAppleMenu(
- short menuItem) /* Chosen menu item */
- {
- Str255 daName; /* Name of the chosen DA */
- short refNum; /* Reference number of the DA, ignored */
-
- if (menuItem != iAbout)
- {
- GetItem( GetMHandle( mApple ), menuItem, /*<*/daName );
- refNum = OpenDeskAcc( daName );
- }
- }
-
-
- /******************************************************************************\
- * Private: DoFileMenu - Handle a File menu item choice
- *
- * This routine is called whenever it’s determined that the chosen menu item was
- * in the File menu. The item number of the chosen menu item is passed in the
- * menuItem parameter.
- \******************************************************************************/
-
- static void DoFileMenu(
- short menuItem) /* Chosen menu item */
- {
- if (menuItem == iOpen)
- (void)DoOpenPictDoc();
- else if (menuItem == iClose)
- {
- if (IsPictDocWindow( FrontWindow() ))
- DoClosePictDoc( FrontWindow() );
- }
- else if (menuItem == iSaveAs)
- {
- if (IsPictDocWindow( FrontWindow() ))
- DoSaveAsPictDoc( FrontWindow() );
- }
- else if (menuItem == iQuit)
- DoQuit();
- }
-
-
- /******************************************************************************\
- * Private: DoEditMenu - Handle a Edit menu item choice
- *
- * This routine is called whenever it’s determined that the chosen menu item was
- * in the Edit menu. The item number of the chosen menu item is passed in the
- * menuItem parameter.
- \******************************************************************************/
-
- static void DoEditMenu(
- short menuItem) /* Chosen menu item */
- {
- SystemEdit( menuItem - 1 );
- }
-
-
- /******************************************************************************\
- * Private: DoEditMenu - Handle a Edit menu item choice
- *
- * This routine is called whenever it’s determined that the chosen menu item was
- * in the Edit menu. The item number of the chosen menu item is passed in the
- * menuItem parameter.
- \******************************************************************************/
-
- static void DoDisplayMenu(
- short menuItem) /* Chosen menu item */
- {
- if (menuItem == 1)
- RestoreColorsPalette();
- else if (menuItem == 2)
- RestoreColorsSlam();
- }
-
-
- /******************************************************************************\
- * Public: FixMenus
- *
- * FixMenus first disables every available menu item. Then the most basic menu
- * items are enabled. The windowKind field of the front window is then checked.
- * If there is a window open, FixMenus calls a routine that’s responsible for
- * that kind of window to enable any menu items that are relevant to that kind of
- * window.
- *
- * If the front window is a modal dialog, then the basic set of menu items are
- * ! enabled, and the entire Apple menu is disabled.
- *
- * After this is done, the menu bar might have to be redrawn to reflect the new
- * conditions. So, FixMenus go through every menu to determine if the state of
- * the entire menu has changed. The MenuGuide records are used to help determine
- * this. If the state of any many has changed, then the menu bar is redrawn.
- \******************************************************************************/
-
- void FixMenus()
- {
- WindowPtr currWindow; /* Pointer to the front-most window */
- MenuHandle aMenu; /* Handle to menu being enabled */
- long oldEnables; /* True if 1+ items enabled when FixMenus called */
- long newEnables; /* True if 1+ items enabled after menus fixed */
- Boolean mustRedraw; /* True if menu bar has to be redrawn */
- short numItems; /* Number of items in a menu */
- short menuIndex; /* Index into menu guide array */
-
- /* Start by disabling all menus */
- ResetMenuItems();
-
- /* Front-most window determines most menu enabling/disabling */
- currWindow = FrontWindow();
-
- /* Depending on the type of the front window, enable appropriate items */
- if (IsDAWindow( currWindow ))
- FixDAMenus();
- else if (IsPictDocWindow( currWindow ))
- FixPictDocMenus( currWindow );
-
- /* Enable some menus */
- aMenu = GetMHandle( mFile );
- EnableItem( aMenu, iOpen );
-
- /* Assume we don’t have to redraw the menu bar */
- mustRedraw = false;
-
- /* Check through every menu to see if there are any enabled items in it */
- for (menuIndex = 0; menuIndex < kNumMenuGuides; menuIndex++)
- {
- /* Grab the old and new enable flags excluding flag for entire menu */
- oldEnables = gMenuGuides[menuIndex].enables & 0xFFFFFFFE;
- newEnables = (**gMenuGuides[menuIndex].theMenu).enableFlags &
- 0xFFFFFFFE;
-
- /* Shift left so that we only see flags for existing items */
- numItems = CountMItems(gMenuGuides [menuIndex].theMenu);
- oldEnables = oldEnables << (31 - numItems);
- newEnables = newEnables << (31 - numItems);
-
- /* Determine if the menu bar must be redrawn */
- if (((oldEnables != 0) && (newEnables == 0)) || numItems == 0)
- {
- /* Had some items enabled, now has no items enabled, redraw */
- DisableItem( gMenuGuides[menuIndex].theMenu, 0 );
- mustRedraw = true;
- }
- else if ((oldEnables == 0) && (newEnables != 0))
- {
- /* Had no items enabled, now has some items enabled, redraw */
- EnableItem( gMenuGuides[menuIndex].theMenu, 0) ;
- mustRedraw = true;
- }
-
- /* Update our copy of the enable flags */
- gMenuGuides[menuIndex].enables = (**gMenuGuides[menuIndex].theMenu).
- enableFlags;
- }
-
- /* If at least one menu has changed state, must redraw the menu bar */
- if (mustRedraw)
- DrawMenuBar();
- }
-
-
- /******************************************************************************\
- * Private: ResetMenuItems - Disable any disableable items and clear marks
- *
- * Disabling all the menu items is done bruteforcedly. It could easily be done
- * by looping through each menu and disabling every item that comes up (disabling
- * the Font menu is done this way), but I thought doing it using the brute-force
- * method was clearer. Then again. . .
- \******************************************************************************/
-
- static void ResetMenuItems ()
- {
- MenuHandle aMenu; /* Handle to each menu we’re disabling */
-
- /* Disable items in the File menu */
- aMenu = GetMHandle( mFile );
- DisableItem( aMenu, iOpen );
- DisableItem( aMenu, iClose );
- DisableItem( aMenu, iSaveAs );
-
- /* Disable items in the Edit menu */
- aMenu = GetMHandle( mEdit );
- DisableItem( aMenu, iUndo );
- DisableItem( aMenu, iCut );
- DisableItem( aMenu, iCopy );
- DisableItem( aMenu, iPaste );
- DisableItem( aMenu, iClear );
- }
-
-
- /******************************************************************************\
- * Private: FixDAMenus - Enable any menu items relevant for desk accessories
- *
- * Desk accessories can use the Edit menu, so the standard Edit menu items are
- * enabled.
- \******************************************************************************/
-
- static void FixDAMenus()
- {
- MenuHandle aMenu; /* Handle to each menu we’re enabling */
-
- /* Disable items in the Process menu */
- aMenu = GetMHandle( mEdit );
- EnableItem( aMenu, iUndo );
- EnableItem( aMenu, iCut );
- EnableItem( aMenu, iCopy );
- EnableItem( aMenu, iPaste );
- EnableItem( aMenu, iClear );
- }
-
-
- /******************************************************************************\
- * Public: DisableAllMenus
- *
- *
- \******************************************************************************/
-
- void DisableAllMenus()
- {
- short menuIndex; /* Index into menu guide array */
-
- /* Check through every menu to see if there are any enabled items in it */
- for (menuIndex = 0; menuIndex < kNumMenuGuides; menuIndex++)
- DisableItem( gMenuGuides[menuIndex].theMenu, 0 );
- }
-
- /******************************************************************************\
- * Public: RestoreAllMenus
- *
- *
- \******************************************************************************/
-
- void ReenableAllMenus()
- {
- short menuIndex; /* Index into menu guide array */
-
- /* Check through every menu to see if there are any enabled items in it */
- for (menuIndex = 0; menuIndex < kNumMenuGuides; menuIndex++)
- if ( gMenuGuides[menuIndex].enables & 1 )
- EnableItem( gMenuGuides[menuIndex].theMenu, 0 );
- }
-